/**
 * SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
 * SPDX-License-Identifier: Mulan PSL v2
 */
/**
 * @file created by ljh 2020/08/19.
 * 用于对ip的严格校验实现
 */
/* eslint-disable */
import {
    ip2int,
    trim
} from "../../format";
import SfVueComponent from '@sxf/sf-vue-component';
let m_multicastBegin = ip2int('224.0.0.0');
let m_multicastEnd = ip2int('239.255.255.255');
let m_classEBegin = ip2int('240.0.0.1');
let m_classEEnd = ip2int('255.255.255.254');
let m_maxIp = ip2int('255.255.255.255');

let validator = {

    lookbackText: _('{0}不是一个环回地址'),
    multicastText: _('{0}不是一个多播地址'),
    classEText: _('{0}不是一个E类地址'),
    broadcastText: _('{0}不是一个广播地址'),
    hostZeroText: _('{0}不是一个网络地址'),
    zeroBeginText: _('{0}的第一个字节不为0'),
    zeroEndText: _('{0}的最后一个字节不为0'),
    hadPortText:_('{0}需要加上端口号'),

    '!lookbackText': _('{0}是一个环回地址'),
    '!multicastText': _('{0}是一个多播地址'),
    '!classEText': _('{0}是一个E类地址'),
    '!broadcastText': _('{0}是一个广播地址'),
    '!hostZeroText': _('{0}是一个网络地址'),
    '!zeroBeginText': _('请输入一个有效的IP地址，如192.168.1.1'),
    '!zeroEndText': _('{0}的最后一个字节为0'),
    '!hadPortText': _('{0}不需要加上端口号'),

    /**
     * 网口ip地址、dhcp验证，同后台一致
     */
    sfIp: function (v, nIp, arrIp, o) {
        var items = ['broadcast', 'multicast', 'classE', 'lookback', 'zeroBegin', 'hostZero'];
        var item;
        for (var i = 0, len = items.length; i < len; i++) {
            item = items[i];
            if (validator[item](v, nIp, arrIp, o)) {
                return validator['!' + item + 'Text'] || false;
            }
        }

        return true;
    },

    /*
     * 不进行需要mask的验证
     * */
    noMaskSfIp: function (v, nIp, arrIp, o) {
        var items = ['multicast', 'classE', 'lookback', 'zeroBegin'];
        var item;
        for (var i = 0, len = items.length; i < len; i++) {
            item = items[i];
            if (validator[item](v, nIp, arrIp, o)) {
                return validator['!' + item + 'Text'] || false;
            }
        }

        return true;
    },


    // 回环地址
    lookback: function (v, nIp, arrIp) {
        return arrIp[0] === '127';
    },


    // 多播地址
    multicast: function (v, nIp) {
        return nIp >= m_multicastBegin && nIp <= m_multicastEnd;
    },

    // e类地址
    classE: function (v, nIp) {
        return nIp >= m_classEBegin && nIp <= m_classEEnd;
    },

    // 以0开始
    zeroBegin: function (v, nIp, arrIp) {
        return arrIp[0] === '0';
    },


    // 以0结束
    zeroEnd: function (v, nIp, arrIp) {
        return arrIp[3] === '0';
    },

    hadPort: function(v){
        return v.indexOf(':')>-1;
    },


    // 是否是广播地址
    broadcast: function (v, nIp, arrIp, o) {
        var mask = getVar(o.netmask);

        if (mask === undefined) {
            mask = '255.255.255.0';
        }

        var nMask = ip2int(mask);
        var nMaxIp = m_maxIp;
        if (nMask === nMaxIp) {
            return nIp === nMaxIp;
        }

        /* jshint bitwise: false */
        return bitEqual((nIp | nMask), nMaxIp);
    },


    // 主机号是否全0
    hostZero: function (v, nIp, arrIp, o) {
        var mask = getVar(o.netmask);

        if (mask === undefined) {
            mask = '255.255.255.0';
        }

        var nMask = ip2int(mask);
        var nMaxIp = m_maxIp;
        var nMinIp = 0;
        if (nMask === nMaxIp) {
            return nIp === 0;
        }

        /* jshint bitwise: false */
        return bitEqual((nIp & (~nMask)), nMinIp);
    }

};




export default {
    /**
     *
     * @param v
     * @param o
     * {
     *      check: 'sfIp, broadcast, multicast, classE, hostZero, zeroBegin, zeroEnd, lookback, !sfIp, !boradcast, !multicast...'  // 检测是否符合这个类型
     *      valid: '1.2.3.4, 2.3.4.5' or /regexp/,  // 白名单，例外的项
     *      invalid: '1.2.3.4, 2.3.4.5' or /regexp/,  // 黑名单，无效的项
     *      sfIpText: '{0}xxx',
     *      broadcastText: '{0}xxx',
     *
     *      checkText: '{0}xxx',
     *
     *      errorText: '{0}xxx'
     *      errText: '{0}xxx'
     * }
     * @returns {Boolean | String}
     */
    validate: function (v, o) {
        let mutilIpv4Validator = SfVueComponent.vtypes.get('multi_ip_or_port');
        o = o || {};

        o.errorText = o.errorText || o.errText;

        v = trim(v);
        var ret = mutilIpv4Validator.verify(v);


        if (ret !== true) {
            return _('校验失败，不符合IPv4格式。') || false;
        }


        if (o.valid) {
            ret = isStrIn(v, o.valid);
            if (ret) {
                return ret;
            }
        }


        if (o.invalid) {

            ret = isStrIn(v, o.invalid);
            if (ret) {
                return getErrorText(o.invalidText || o.errorText, v) || false;
            }

        }


        if (o.check) {
            var checkText = o.checkText || _('{0}不是一个有效的输入');

            var checkList = o.check.split(',');
            var ipArray = v.replace(/\s/g, '').split('.');
            var nIp = ip2int(v);
            var isItemValid;

            var item;
            var validateFn;
            for (var i = 0, len = checkList.length; i < len; i++) {
                item = trim(checkList[i]);
                validateFn = validator[item.replace('!', '')];
                if (validateFn) {
                    isItemValid = validateFn(v, nIp, ipArray, o, item);
                    isItemValid = item[0] === '!' ? isItemValid !== true : isItemValid;
                    if (isItemValid !== true) {
                        return getErrorText((typeof (isItemValid) === 'string' ? isItemValid :
                            (o[item + 'Text'] || validator[item + 'Text'] || checkText || o.erorText)), o.netmask ? _('指定IP（{0}/{1}）', v, o.netmask) : v) || false;
                    }
                }
            }
        }


        return true;
    },
    text: _('请输入一个有效的IP地址，如192.168.0.1'),
    mask: /[\d\.]/i
};


function getErrorText(str, v) {
    if (str) {
        return str.replace('{0}', v);
    }
}

/**
 * 验证是否等于某些字符串或符合正则表达式
 * @param v
 * @param regExp
 * @returns {boolean}
 */
function isStrIn(v, regExp) {
    var ret = true;

    if (typeof (regExp) === 'string') {
        ret = regExp.indexOf(v) !== -1;
    } else if (Object.prototype.toString(regExp).indexOf('RegExp') !== -1) {
        ret = regExp.test(v);
    }
    return ret;
}



function getVar(arg) {
    if (arg === undefined) {
        return;
    }
    return typeof (arg) === 'function' ? arg() : arg;
}


function bitEqual(a, b) {
    /* jshint bitwise: false */
    return (a >>> 0) === (b >>> 0);
}
